using System;
using System.Collections.Generic;
using Spine.Unity;
using UnityEditor;
using UnityEngine;

[Serializable]
public class SkeletonTouchUtilityAreaTrigger
{
    public SkeletonTouchUtilityAreaType areaType;

    public Vector2 triggerPosition;
    public float radius;
    private float sqrRadius;

    public List<SkeletonTouchUtilityEvent> enterEvents = new();
    public List<SkeletonTouchUtilityEvent> stayEvents = new();
    public List<SkeletonTouchUtilityEvent> exitEvents = new();
    public List<SkeletonTouchUtilityEvent> releaseEvents = new();

    private bool isEnter;
    private bool isStay;

    public void Init()
    {
        sqrRadius = radius * radius;
    }

    public void Update(SkeletonGraphic role, SkeletonUtilityBone bone, Vector2 worldPos)
    {
        bool onTrigger = Check(bone, worldPos);
        if (onTrigger)
        {
            if (!isEnter)
            {
                isEnter = true;
                Enter(role);
            }

            isStay = true;
            Stay(role);
        }
        else
        {
            if (isStay || isEnter)
            {
                isStay = false;
                isEnter = false;
                Exit(role);
            }
        }
    }

    private bool Check(SkeletonUtilityBone bone, Vector2 worldPos)
    {
        // 忽略Y轴，只在XZ平面判断
        Vector2 point2D = new Vector2(worldPos.x, worldPos.y);
        Vector2 center2D = new Vector2();
        if (areaType == SkeletonTouchUtilityAreaType.Local)
        {
            center2D = new Vector2(bone.transform.position.x + triggerPosition.x, bone.transform.position.y + triggerPosition.y);
        }
        else if (areaType == SkeletonTouchUtilityAreaType.World)
        {
            center2D = new Vector2(triggerPosition.x, triggerPosition.y);
        }

        float sqrDistance = (point2D - center2D).sqrMagnitude;

        return sqrDistance <= sqrRadius;
    }

    private void Enter(SkeletonGraphic role)
    {
        foreach (var enterEvent in enterEvents)
        {
            enterEvent.Invoke(role);
        }
    }

    private void Stay(SkeletonGraphic role)
    {
        foreach (var stayEvent in stayEvents)
        {
            stayEvent.Invoke(role);
        }
    }

    private void Exit(SkeletonGraphic role)
    {
        foreach (var exitEvent in exitEvents)
        {
            exitEvent.Invoke(role);
        }
    }

    public void Release(SkeletonGraphic role, SkeletonUtilityBone bone, Vector2 worldPos)
    {
        if (Check(bone, worldPos))
        {
            foreach (var releaseEvent in releaseEvents)
            {
                releaseEvent.Invoke(role);
            }
        }
    }

    public void OnDrawGizmosSelected(SkeletonUtilityBone bone)
    {
        Vector2 center2D = new Vector2();
        if (areaType == SkeletonTouchUtilityAreaType.Local)
        {
            center2D = new Vector2(bone.transform.position.x + triggerPosition.x, bone.transform.position.y + triggerPosition.y);
        }
        else if (areaType == SkeletonTouchUtilityAreaType.World)
        {
            center2D = new Vector2(triggerPosition.x, triggerPosition.y);
        }

#if UNITY_EDITOR
        Handles.color = Color.red;
        int segments = 32;
        Vector3[] points = new Vector3[segments + 1];
        for (int i = 0; i < segments; i++)
        {
            float angle = (float)i / segments * 360f;
            points[i] = new Vector3(center2D.x, center2D.y, bone.transform.position.z) + Quaternion.Euler(0, 0, angle) * Vector3.up * radius;
        }

        points[segments] = points[0];
        Handles.DrawPolyLine(points);
#endif
    }
}